include "exceptions.thrift"

typedef i16 UserId
typedef string Word
typedef string Letter   #maybe it's better to define byte as Letter

enum ErrorCode {        #First common errors which comes without message to save traffic
    WRONG_MOVE = 1,
    WRONG_PARAMETERS = 2,
    NO_PERMISSIONS = 3,
    ERROR = 4           #This comes with message
}

enum EventType {	# Type of the event returned with wait_ calls
    GAME_START = 1,	# game started. InitialWord added
    GAME_STOP = 2,  # game stopped
    USER_REGISTERED = 3,# new user register. UserId added
    MOVE_MADE = 4	# move made. Move added
}

struct Configuration {  #Need to decide the structure of configuration
}

struct Coordinates {    #For now only regular plain fields (rectangle, hexagon, ...)
    1: byte x,
    2: byte y
}

struct InitialWord {
    1: Word word,
    2: Coordinates coord
}

struct Move {
    1: Coordinates coord,
    2: Letter letter,
    3: Word word
}

struct Event {		#Event, returned with wait_ calls
    1: EventType type,
    2: optional Move move,
    3: optional Word iword,
    4: optional UserId id
}


service GameService {
    #Ping, returns True or False
    bool ping(),

    #Register user, throws exception when game is started or full
    bool register_user(1:UserId id) throws(1:exceptions.RegistrationError exc),

    #Start game. Return first word. Only game admin may start the game.
    Word start_game(1:UserId id) throws(1:exceptions.AccessViolation acc_exc, 2:exceptions.NotRegistered reg_exc),
    #Stop the game. Only game admin may start the game.
    bool stop_game(1:UserId id) throws(1:exceptions.AccessViolation acc_exc, 2:exceptions.NotRegistered reg_exc),
    #Sets the configuration
    bool set_config(1:Configuration config) throws(1:exceptions.AccessViolation acc_exc, 2:exceptions.NotRegistered reg_exc)
    #Gets configuration
    Configuration get_config(1:UserId id) throws(1:exceptions.NotRegistered reg_exc)

    #Makes the move. If the move is not correct it raises an exception
    bool make_move(1:UserId id, 2:Move move) throws(1:exceptions.NotRegistered reg_exc, 2:exceptions.InvalidMove)

    #Long polling
    Event wait_for_event(1:UserId id) throws(1:exceptions.NotRegistered reg_exc)

}